#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#define BUFSIZE  1024

int main()
{
	int ret;
	int sockfd;
	struct iovec iov;
	struct msghdr msg;
	struct sockaddr_nl sa;
	char *buf, *strbuf;

	buf = calloc(1, BUFSIZE);
	if(buf == NULL) {
		printf("calloc() error !\n");
		return -1;
	}

	memset(&iov, 0, sizeof(iov));
	iov.iov_base = (void *)buf;
	iov.iov_len = BUFSIZE;

	memset(&sa, 0, sizeof(sa));
	sa.nl_pid = 0;//getpid(); both is ok
	sa.nl_pad = 0;//reserse
	sa.nl_family = AF_NETLINK;
	sa.nl_groups = NETLINK_KOBJECT_UEVENT;

	memset(&msg, 0, sizeof(msg));
	msg.msg_name = (void *)&sa;
	msg.msg_namelen = sizeof(sa);
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;

	sockfd  = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
	if(sockfd == -1) {
		printf("socket creating failed:%s\n",strerror(errno));
		return -1;
	}

	ret = bind(sockfd, (struct sockaddr *)&sa, sizeof(sa));
	if(ret == -1) {
		printf("bind error:%s\n",strerror(errno));
		return -1;
	}

	int len, i;
	while(1) {
		len = recvmsg(sockfd, &msg, 0);
		if(len < 0) {
			printf("receive error\n");
		}

		for(i = 0; i < len; i++) {
			if(buf[i] == '\0') {
				buf[i] = '\n';
			}
		}
		printf("[EVENT BUF]:\n%s\n\n", buf);

		strbuf = NULL;
		strbuf = strstr(buf, "UEVENT_STATE=IDLE");
		if (strbuf != NULL) {
			printf("Woooo: uevent is: %s\n", "UEVENT_STATE=IDLE");
		}

		strbuf = NULL;
		strbuf = strstr(buf, "UEVENT_STATE=TRIGER");
		if (strbuf != NULL) {
			printf("Woooo: uevent is: %s\n", "UEVENT_STATE=TRIGER");
		}
	}
}
